import { AxiosError } from 'axios'
import { ElMessageBox } from 'element-plus'
import { ElMessage } from 'element-plus/es'
import { Router } from '@/router'
import { afterLogout } from '@/service/admin-info.service'
import { ApiResponse } from '@/service/api.service'
import { throttle } from '@lhy-assist/utils'
import { escapeHtml } from '@vue/shared'

/**
 * 接口常规错误处理
 * @param e
 */
export function errorHandler(e: AxiosError<ApiResponse>) {
  const flatMessage = (msgs: string | string[]) => (Array.isArray(msgs) ? msgs.join('\n') : msgs)
  ElMessage.warning(flatMessage(e.response?.data?.msg || e.message))
}

/**
 * 未授权处理
 * @param e
 */
export const unauthorizedHandler = throttle((e: AxiosError<ApiResponse>) => {
  ElMessage.warning(e.message)
  afterLogout()
  Router.navigateToLogin()
}, 500) as (e: AxiosError<ApiResponse>) => void

const errors: AxiosError<ApiResponse>[] = []
const exceptionElId = `exception-handler-container-${Date.now()}`

/**
 * 接口异常处理
 * @param err
 */
export function exceptionHandler(err: AxiosError<ApiResponse>) {
  if (!errors.length) {
    ElMessageBox.confirm(`<div id="${exceptionElId}">${buildErrorContent(err)}</div>`, '系统异常', {
      dangerouslyUseHTMLString: true,
      confirmButtonText: '我已知晓',
      showCancelButton: false,
      closeOnClickModal: false,
      closeOnPressEscape: false,
      showClose: false,
      customClass: 'message-box-exception',
    }).then(() => {
      errors.splice(0, errors.length)
    })
  } else {
    const errorEl = document.querySelector(`#${exceptionElId}`)
    if (errorEl) {
      errorEl.innerHTML += buildErrorContent(err)
    }
  }
  errors.push(err)
}

/**
 * 错误信息体
 * @param err
 */
function buildErrorContent(err: AxiosError<ApiResponse>) {
  return `
    <div class="exception-item">
      <div><label>Code: </label>${escapeHtml(err.code)}</div>
      <div><label>Url: </label>${escapeHtml(err.config?.url)}</div>
      <div><label>Message: </label>
          <div class="exception-item-stack">${escapeHtml(err.response?.data?.msg || err.message)}</div>
      </div>
    </div>
  `
}
